from dataclasses import dataclass, field
from .bookmark import list_bookmarks
import json
import traceback


@dataclass
class Tag:
    uid: int = -1
    name: str = ""
    kws: set[str] = field(default_factory=set)

    def to_dict(self):
        return {
            "uid": self.uid,
            "name": self.name,
            "kws": list(self.kws),
        }

    @staticmethod
    def from_dict(dit):
        tag = Tag()
        tag.uid = dit["uid"]
        tag.name = dit["name"]
        tag.kws = set(dit["kws"])
        return tag


EMPTY_TAG = Tag()

_max_id = 0
_tags: dict[int, Tag] = dict()


def load(file_path):
    global _max_id, _tags
    try:
        with open(file_path, "rb") as f:
            obj = json.load(f)
            _max_id = obj["max_id"]
            _tags = dict()
            for dit in obj["tags"]:
                tag = Tag.from_dict(dit)
                _tags[tag.uid] = tag
            return True
    except:
        traceback.print_exc()
        _max_id = 0
        _tags = dict()
    return False


def save(file_path):
    try:
        with open(file_path, "wt", encoding="utf-8") as f:
            obj = {
                "max_id": _max_id,
                "tags": [tag.to_dict() for tag in _tags.values()]
            }
            json.dump(obj, f, indent=2)
    except:
        traceback.print_exc()

def add_tag(tag: Tag):
    global _max_id
    if tag.uid < 0:
        tag.uid = _max_id
        _max_id += 1
        _tags[tag.uid] = tag

def update_tag(tag: Tag):
    if tag.uid in _tags:
        _tags[tag.uid] = tag

def list_tags():
    odlist = list(_tags.values())
    odlist.sort(key=lambda item: item.uid)
    return odlist

def get_tag_by_name(name: str) -> Tag | None:
    for tag in _tags.values():
        if tag.name == name:
            return tag
    return None

def get_tag_by_id(tag_uid: int) -> Tag | None:
    if tag_uid in _tags:
        return _tags[tag_uid]
    return None

def delete_tag(tag_uid: int):
    if tag_uid in _tags:
        # 级联删除所有书签中标签记录
        for bmk in list_bookmarks():
            bmk.tags.discard(tag_uid)
        del _tags[tag_uid]
